package lumis.portal.presentation.tag.el;

import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.util.value.IValueMap;

import lumis.portal.presentation.core.HTMLFragmentComponent;
import lumis.portal.presentation.core.IPageRenderer;
import lumis.portal.presentation.core.LayoutFilePage;
import lumis.util.HtmlUtil;
import lumis.util.XmlUtil;

/**
 * Component used to output a EL expression in the HTML body. Usage is
 * equivalent of the 
 * <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSTL4.html#wp85708">JSTL</a>
 * core out element. The following attributes in the HTML element are used:
 * <ul>
 * <li><code>value</code>: contains the value to be evaluated. It may contain
 * EL expression inside the ${ ... } area.</li>
 * <li><code>escapeXml</code>: indicates if the evaluated value should be
 * escaped. This attribute is optional and default is <code>true</code></li>
 * <li><code>default</code>: the value to be used if the <code>value</code>
 * evaluates to <code>null</code> or an empty string. If not specified, the
 * default is an empty string.</li>
 * </ul>
 * <p>
 * The attributes will have any HTML entity in their value decoded.
 * <p>
 * Examples:
 * <table border="1">
 * <tr>
 * <th>Layout File Code</th><th>Output (HTML source code)</th>
 * </tr>
 * <tr>
 * <td><code>&lt;el:out value="${1+1}&amp;quot;"&gt;Example HTML&lt;/el:out&gt;</code></td>
 * <td>2&amp;quot;</td>
 * </tr>
 * <tr>
 * <td><code>&lt;el:out value="${1+1}&amp;quot;" escapeXml="false"&gt;Example HTML&lt;/el:out&gt;</code></td>
 * <td>2&quot;</td>
 * </tr>
 * <tr>
 * <td><code>&lt;el:out value="${null}" default="&amp;quot;"&gt;Example HTML&lt;/el:out&gt;</code></td>
 * <td>&amp;quot;</td>
 * </tr>
 * <tr>
 * <td><code>&lt;el:out value="${null}" escapeXml="false" default="&amp;quot;"&gt;Example HTML&lt;/el:out&gt;</code></td>
 * <td>&quot;</td>
 * </tr>
 * </table>
 *
 * @version $Revision: 13093 $ $Date: 2011-05-28 18:40:18 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
@SuppressWarnings("serial")
public class OutComponent extends HTMLFragmentComponent
{
	public OutComponent(String id,  boolean autoRenderBodyOnly)
	{
		super(id, autoRenderBodyOnly);
	}

	@Override
	protected CharSequence getHTMLFragment(MarkupStream markupStream, ComponentTag openTag)
	{
		// read value
		IValueMap attributes = openTag.getAttributes();
		String value = attributes.getString("value");
		CharSequence result;
		if (value != null)
		{
			// evaluate value
			IPageRenderer pageRenderer = ((LayoutFilePage)getPage()).getPageRenderer();
			value = HtmlUtil.decode(value);
			result = pageRenderer.evaluateEL(value);
		}
		else
		{
			result = null;
		}

		// use default if necessary
		if (result == null)
		{
			CharSequence defaultValue = attributes.getCharSequence("default");
			if (defaultValue != null)
				defaultValue = HtmlUtil.decode(defaultValue.toString());
			result = defaultValue;
		}
		
		// escape result if necessary
		if (result != null)
		{
			// getAsBoolean(String, boolean) has bug WICKET-2787 to be fixed in 1.4.8
			// so using getAsBoolean(String) for now
			Boolean escapeXml = attributes.getAsBoolean("escapeXml");
			if (escapeXml == null)
				escapeXml = Boolean.TRUE;
			if (escapeXml)
				result = XmlUtil.encodeXml(result.toString());
		}
		
		return result;
	}
}
